﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using FizzBuzzCore.Interfaces;

namespace FizzBuzzCore
{
    /// <summary>
    /// Supports the FizzBuzz assignment
    /// FizzBuzz prints Fizz is the number is divisble by 3 only, buzz if it is divisible by 5 only and FizzBuzz, if its divisible by both
    /// FizzBuzz prints the number if its divisble by neither 3 nor 5
    /// </summary>
    public class FizzBuzz : IFizzBuzz
    {
        private IList<string> fizzBuzzList;
        private short lowerLimit;
        private bool isLowerLimitDirty;
        private short upperLimit;
        private bool isUpperLimitDirty;

        /// <summary>
        /// Constructor.
        /// </summary>
        protected FizzBuzz()
        {
            fizzBuzzList = new List<string> { FizzBuzzResource.setLowerUpperLimitText };
        }

        /// <summary>
        /// Contains a list of numbers and FizzBuzz tokens
        /// </summary>
        public IList<string> FizzBuzzList
        {
            get
            {
                if (isUpperLimitDirty || isLowerLimitDirty)
                {
                    fizzBuzzList = FizzBuzzLogic.GetFizzBuzzSequence(LowerLimit, UpperLimit);
                    isLowerLimitDirty = isUpperLimitDirty = false;
                }
                return fizzBuzzList;
            }
        }

        /// <summary>
        /// Lower FizzBuzz sequence limit
        /// </summary>
        public short LowerLimit
        {
            get { return lowerLimit; }
            set
            {
                if (lowerLimit != value)
                {
                    lowerLimit = value;
                    isLowerLimitDirty = true;
                }
            }
        }

        /// <summary>
        /// Has the lower FizzBuzz limit changed since generating the FizzBuzz sequence 
        /// </summary>
        public bool IsLowerLimitDirty
        {
            get { return isLowerLimitDirty; }
        }

        /// <summary>
        /// Upper FizzBuzz sequence limit
        /// </summary>
        public short UpperLimit
        {
            get { return upperLimit; }
            set
            {
                if (upperLimit != value)
                {
                    upperLimit = value;
                    isUpperLimitDirty = true;
                }
            }
        }

        /// <summary>
        /// Has the upper FizzBuzz limit changed since generating the FizzBuzz sequence 
        /// </summary>
        public bool IsUpperLimitDirty
        {
            get { return isUpperLimitDirty; }
        }

        /// <summary>
        /// Generates new IFizzBuzz object
        /// </summary>
        /// <returns>IFizzBuzz object</returns>
        public static IFizzBuzz NewObject()
        {
            return new FizzBuzz();
        }
    }
}
